
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;

using Swaf;
using Swaf.Config;
using Swaf.Resource;

namespace Swaf.FtpServer
{
	/// <summary>
	/// Summary description for FtpConfigPartner.
	/// </summary>
	public class FtpConfigPartner : IConfigPartner
	{
		protected IList m_servers = new ArrayList();
		protected IDictionary m_sessions = new Hashtable();

		public FtpConfigPartner(IApplication app)
		{
			//Intentionally left blank.
		}

		void addServer(FtpServer server)
		{
			m_servers.Add(server);
		}

		private void OnAppShutdown(IApplication app)
		{
			foreach(FtpServer server in m_servers)
				server.stop();
		}

		protected internal void addSession(FtpSession session)
		{
			m_sessions[session.SessionId] = session;
		}

		protected internal void removeSession(FtpSession session)
		{
			m_sessions.Remove(session.SessionId);
		}

		#region IConfigPartner Members

		public void checkConfigStatus()
		{
			((IAppManagement)Application.globalApp).OnAppShutdown +=new AppShutdownRequest(OnAppShutdown);
			foreach(FtpServer server in m_servers)
				server.start();
		}

		public void registerForConfig(IConfigManager config)
		{
			config.registerHandler("...<FtpServer>", new ServerConfigHandler(this));
			config.registerHandler("...<FtpServer> <FilePattern>", new FilePatternConfigHandler(this));
		}

		#endregion

		protected internal class ServerConfigHandler : ConfigHandler
		{
			protected static string[] s_legalAttributes = {"ip","port", "baseDirectory"};
			public ServerConfigHandler(FtpConfigPartner mgr)
			{
				m_mgr = mgr;
			}
			public override void  executeBefore(IConfigElement configInfo)
			{
				IResourceManager resMgr = Application.globalApp.resMgr;
				IApplication app = Application.currentApp;

				configInfo.checkIllegalAttributes(s_legalAttributes);
				string ip = resMgr.resolve(configInfo.getAttribute("ip"));
				string port = configInfo.getAttribute("port");
				string baseDirectory = resMgr.resolve(configInfo.getAttribute("baseDirectory"));
				configInfo.Context["ftpServer"] = new FtpServer(m_mgr, ip, port, baseDirectory);
				Application.currentApp.Log.println(Application.NORMAL_STARTUP_LOG_LEVEL,
					"Creating FTP server at ip {0}, port {1} using directory \"{2}\"", ip, port, baseDirectory);
			}
			public override void executeAfter(IConfigElement configInfo)
			{
				m_mgr.addServer((FtpServer)configInfo.Context["ftpServer"]);
				configInfo.Context.Remove("ftpServer");
			}

			private FtpConfigPartner m_mgr;
		}

		protected internal class FilePatternConfigHandler : ConfigHandler
		{
			protected static string[] s_legalAttributes = {"direction", "bizRule"};
			public FilePatternConfigHandler(FtpConfigPartner mgr)
			{
				m_mgr = mgr;
			}
			public override void  executeBefore(IConfigElement configInfo)
			{
				IApplication app = Application.currentApp;
				configInfo.checkIllegalAttributes(s_legalAttributes);
				string direction = configInfo.getAttribute("direction","in").ToLower();
				bool fileIn = true;
				if(direction == "in")
					fileIn = true;
				else if(direction == "out")
					fileIn = false;
				else
					throw new BadConfigException("FTP File Pattern Direction is invalid", "in or out", direction);
				string bizRule = configInfo.getAttribute("bizRule");
				string filePattern = configInfo.getChildText();
				FtpServer svr = (FtpServer)configInfo.Context["ftpServer"];
				svr.defineBizRuleHandler(bizRule, filePattern, fileIn);
				Application.currentApp.Log.println(Application.VERBOSE_STARTUP_LOG_LEVEL,
					"	Defining FTP Server file pattern handler with direction {0} for files matching {1} to call the bizRule {2}",
					direction, filePattern, bizRule);
			}
			private FtpConfigPartner m_mgr;
		}

	}
}
